package com.example.view;

import com.example.entry.DeviceEntry;
import com.example.entry.LevelEntry;
import com.example.struct.Edge;
import com.example.struct.YibihuaGraph;
import com.example.utils.AdbShellUtil;
import com.example.utils.ImageUtil;
import com.example.utils.PropertiesUtil;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author 我叫程晓非
 * @desc 主窗口类
 * @date 2021-11-09
 * @version 1.0
 */
public class MainFrame extends JFrame implements ActionListener, ItemListener ,KeyListener{
    public final static String USER_CONFIG_FOLDER = "config";
    public final static String USER_SCREENSHOT_FOLDER = "screenshot";
    public final static String USER_CONFIG_SUFFIX = ".properties";

    public final static String IMAGE_HONGBAO_ICON = "src/image/hongbao.png";
    public final static String IMAGE_UP_BUTTON = "src/image/up.png";
    public final static String IMAGE_DOWN_BUTTON = "src/image/down.png";
    public final static String IMAGE_RIGHT_BUTTON = "src/image/right.png";
    public final static String IMAGE_LEFT_BUTTON = "src/image/left.png";

    public final static String IMAGE_START_BUTTON = "src/image/start.png";


    private boolean isRun;
    //
    private JPanel mainPanel;
    private JPanel leftPanel;
    private DisplayJPanel centerPanel;
    private JPanel rightPanel;
    //状态栏
    //设备列表，key-id,value-型号
    private HashMap<String,String> deviceMap=new HashMap<>();
    private final JComboBox<DeviceEntry<String,String>> deviceComboBox = new JComboBox<>();
    private final JComboBox<LevelEntry<Integer,String>> levelComboBox = new JComboBox<>();
    private DeviceEntry<String,String> selectedDeviceEntry = null;
    //刷新线程
    private static Thread refreshThread;


    //截图区域
    private JLabel screenshotLabel = new JLabel();

    private YibihuaGraph yibihuaGraph;

    public MainFrame(String title){
        super(title);
        //检查是否存在配置文件，没有就加上
        File userConfigFolder = new File("./"+USER_CONFIG_FOLDER);
        File userScreenshotFolder = new File("./"+USER_SCREENSHOT_FOLDER);
        File userConfigFile = new File("./"+USER_CONFIG_FOLDER+"/"+"default"+USER_CONFIG_SUFFIX);
        if(!userConfigFolder.exists()){
            userConfigFolder.mkdir();
        }
        if(!userScreenshotFolder.exists()){
            userScreenshotFolder.mkdir();
        }
        if(!userConfigFile.exists()){
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.x","50");
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.y","180");
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.width","300");
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.height","300");

            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.x","40");
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.y","550");
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.width","30");
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.height","30");

            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"screen.height","1920");
            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"screen.width","1080");

            PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"config.level","1");
        }
        isRun  = true;
        screenshotLabel.setBackground(Color.BLUE);

        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        initView();
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                isRun = false;
                if(refreshThread!=null){
                    refreshThread.interrupt();
                }
                super.windowClosing(e);
            }
        });

        setVisible(true);
        //设置居中
        setLocationRelativeTo(null);
        setResizable(false);
        DisplayJPanel.PANEL_WIDTH = centerPanel.getWidth();
        DisplayJPanel.PANEL_HEIGHT = centerPanel.getHeight();
        int height = DisplayJPanel.PANEL_HEIGHT - 2*DisplayJPanel.padding;
        String screenHeightStr = PropertiesUtil.readValue("./"+MainFrame.USER_CONFIG_FOLDER+"/"+"default"+MainFrame.USER_CONFIG_SUFFIX,"screen.height");
        int screenHeight = Integer.parseInt(screenHeightStr);


        String screenWidthStr = PropertiesUtil.readValue("./"+MainFrame.USER_CONFIG_FOLDER+"/"+"default"+MainFrame.USER_CONFIG_SUFFIX,"screen.height");
        int screenWidth = Integer.parseInt(screenWidthStr);


        DisplayJPanel.scale = screenHeight/(float)height;
        DisplayJPanel.y = DisplayJPanel.padding;
        DisplayJPanel.x = (DisplayJPanel.PANEL_WIDTH - (int)(screenWidth/DisplayJPanel.scale))/2;
        this.addKeyListener(this);
        this.setFocusable(true);


    }
    private void initView(){
        this.setIconImage(new ImageIcon(IMAGE_HONGBAO_ICON).getImage());
        String levelStr = PropertiesUtil.readValue("./"+MainFrame.USER_CONFIG_FOLDER+"/"+"default"+MainFrame.USER_CONFIG_SUFFIX,"config.level");
        int level = Integer.parseInt(levelStr);
        yibihuaGraph = new YibihuaGraph(true,level);
        this.setSize(1280,720);
        mainPanel = new JPanel();
        mainPanel.setLayout(new GridLayout(1,3,3,3));
        initLeftPanel();
        initCenterPanel();
        initRightPanel();
        add(mainPanel);

    }
    //连接状态
    private JLabel connectStatusLabel = new JLabel("连接状态:");
    private JLabel connectStatusText = new JLabel("未连接");
    private JLabel selectDeviceLabel = new JLabel("当前设备:");

    private JButton connectButton = new JButton("连接");
    private JButton refreshButton = new JButton("刷新");

    private JLabel resolutionRatioLabel = new JLabel("设备分辨率:");
    private JLabel showResolutionRatioText = new JLabel("...");

    private JLabel levelSettingLabel = new JLabel("难度:");


    private void initLeftPanel(){
        GridBagLayout gridBagLayout=new GridBagLayout();
        leftPanel = new JPanel();
        leftPanel.setLayout(gridBagLayout);
        leftPanel.setBorder(BorderFactory.createTitledBorder("状态栏"));
        //row1 连接状态
        GridBagConstraints gba_line11=new GridBagConstraints();
        gba_line11.insets = new Insets(0,10,5,5);
        gba_line11.gridx = 0;
        gba_line11.gridy = 0;
//        gba_line11.weightx=10.0;
        gridBagLayout.setConstraints(connectStatusLabel,gba_line11);
        leftPanel.add(connectStatusLabel);


        GridBagConstraints gba_line12=new GridBagConstraints();
        gba_line12.insets = new Insets(0,10,5,5);
        gba_line12.gridx = 1;
        gba_line12.gridy = 0;
//        gba_line12.weightx=10.0;
//        gba_line12.gridwidth = GridBagConstraints.REMAINDER;
        gridBagLayout.setConstraints(connectStatusText,gba_line12);
        leftPanel.add(connectStatusText);
        //row2 设备刷新
        GridBagConstraints gba_line21=new GridBagConstraints();
        gba_line21.insets = new Insets(0,10,5,5);
        gba_line21.gridx = 0;
        gba_line21.gridy = 1;
//        gba_line21.weightx=10.0;
        gridBagLayout.setConstraints(selectDeviceLabel,gba_line21);
        leftPanel.add(selectDeviceLabel);


        GridBagConstraints gba_line22=new GridBagConstraints();
        gba_line22.insets = new Insets(0,10,5,5);
        gba_line22.gridx = 1;
        gba_line22.gridy = 1;
//        gba_line22.weightx=10.0;
//        gba_line22.gridwidth = GridBagConstraints.REMAINDER;
        gridBagLayout.setConstraints(deviceComboBox,gba_line22);
        deviceComboBox.addItemListener(this);
        deviceComboBox.setSize(65,30);
        leftPanel.add(deviceComboBox);
        if(deviceComboBox.getItemCount() == 0){
            deviceComboBox.addItem(new DeviceEntry<String, String>("0","请选择设备"));
        }

        GridBagConstraints gba_line23=new GridBagConstraints();
        gba_line23.insets = new Insets(0,10,5,5);
        gba_line23.gridx = 2;
        gba_line23.gridy = 1;
        gridBagLayout.setConstraints(connectButton,gba_line23);
        connectButton.setActionCommand("connectButton");
        connectButton.addActionListener(this);
        leftPanel.add(connectButton);

        GridBagConstraints gba_line24=new GridBagConstraints();
        gba_line24.insets = new Insets(0,10,5,5);
        gba_line24.gridx = 3;
        gba_line24.gridy = 1;
        gridBagLayout.setConstraints(refreshButton,gba_line24);
        refreshButton.setActionCommand("refreshButton");
        refreshButton.addActionListener(this);
        leftPanel.add(refreshButton);


        //row3 分辨率
        GridBagConstraints gba_line31=new GridBagConstraints();
        gba_line31.insets = new Insets(0,10,5,5);
        gba_line31.gridx = 0;
        gba_line31.gridy = 2;
        gridBagLayout.setConstraints(resolutionRatioLabel,gba_line31);
        leftPanel.add(resolutionRatioLabel);


        GridBagConstraints gba_line32=new GridBagConstraints();
        gba_line32.insets = new Insets(0,10,5,5);
        gba_line32.gridx = 1;
        gba_line32.gridy = 2;
        gridBagLayout.setConstraints(showResolutionRatioText,gba_line32);
        leftPanel.add(showResolutionRatioText);

        //row4 难度设置
        GridBagConstraints gba_line41=new GridBagConstraints();
        gba_line41.insets = new Insets(0,10,5,5);
        gba_line41.gridx = 0;
        gba_line41.gridy = 3;
        gridBagLayout.setConstraints(levelSettingLabel,gba_line41);
        leftPanel.add(levelSettingLabel);

        GridBagConstraints gba_line42=new GridBagConstraints();
        gba_line42.insets = new Insets(0,10,5,5);
        gba_line42.gridx = 1;
        gba_line42.gridy = 3;
        gridBagLayout.setConstraints(levelComboBox,gba_line42);
        LevelEntry<Integer,String> levelEntry0 = new LevelEntry<>(1,"简单");
        LevelEntry<Integer,String> levelEntry1 = new LevelEntry<>(2,"普通");
        LevelEntry<Integer,String> levelEntry2 = new LevelEntry<>(3,"困难");

        levelComboBox.addItem(levelEntry0);
        levelComboBox.addItem(levelEntry1);
        levelComboBox.addItem(levelEntry2);
        levelComboBox.addItemListener(this);
        if(yibihuaGraph.getLevel() !=1){
            levelComboBox.setSelectedIndex(yibihuaGraph.getLevel()-1);
        }
        leftPanel.add(levelComboBox);


        mainPanel.add(leftPanel);
//        leftPanel.setBackground(Color.BLUE);
    }
    private void initCenterPanel(){
        centerPanel = new DisplayJPanel(yibihuaGraph.getLevel());
//        centerPanel.setLayout(null);
        centerPanel.setBorder(BorderFactory.createTitledBorder("截图区域"));
        //窗口高度、窗口1/3宽度
        screenshotLabel.setBounds(0,0,426,720);
        screenshotLabel.setVisible(true);
        centerPanel.add(screenshotLabel);
        mainPanel.add(centerPanel);


//        centerPanel.setBackground(Color.GREEN);
    }

    private JLabel locationLabel = new JLabel("位置:");
    private JButton leftLocationButton = new JButton();
    private JButton rightLocationButton = new JButton();
    private JButton upLocationButton = new JButton();
    private JButton downLocationButton = new JButton();


    private JLabel scaleLabel = new JLabel("缩放:");
    private JButton leftScaleButton = new JButton();
    private JButton rightScaleButton = new JButton();
    private JButton upScaleButton = new JButton();
    private JButton downScaleButton = new JButton();



    private JButton startButton = new JButton();
    private void initRightPanel(){
        rightPanel = new JPanel();
        rightPanel.setLayout(null);
        locationLabel.setBounds(30,80,100,30);
        upLocationButton.setBounds(60,141,41,41);
        upLocationButton.setIcon(new ImageIcon(IMAGE_UP_BUTTON));

        rightLocationButton.setBounds(111,191,41,41);
        rightLocationButton.setIcon(new ImageIcon(IMAGE_RIGHT_BUTTON));

        leftLocationButton.setBounds(10,191,41,41);
        leftLocationButton.setIcon(new ImageIcon(IMAGE_LEFT_BUTTON));

        downLocationButton.setBounds(60,191,41,41);
        downLocationButton.setIcon(new ImageIcon(IMAGE_DOWN_BUTTON));

        rightPanel.add(locationLabel);
        rightPanel.add(upLocationButton);
        rightPanel.add(rightLocationButton);
        rightPanel.add(leftLocationButton);
        rightPanel.add(downLocationButton);
        int top = 220;

        scaleLabel.setBounds(30,80+top,100,30);
        upScaleButton.setBounds(60,141+top,41,41);
        upScaleButton.setIcon(new ImageIcon(IMAGE_UP_BUTTON));

        rightScaleButton.setBounds(111,191+top,41,41);
        rightScaleButton.setIcon(new ImageIcon(IMAGE_RIGHT_BUTTON));

        leftScaleButton.setBounds(10,191+top,41,41);
        leftScaleButton.setIcon(new ImageIcon(IMAGE_LEFT_BUTTON));

        downScaleButton.setBounds(60,191+top,41,41);
        downScaleButton.setIcon(new ImageIcon(IMAGE_DOWN_BUTTON));

        rightPanel.add(scaleLabel);
        rightPanel.add(upScaleButton);
        rightPanel.add(rightScaleButton);
        rightPanel.add(leftScaleButton);
        rightPanel.add(downScaleButton);

        startButton.setBounds(20,260+top,80,41);
        startButton.setIcon(new ImageIcon(IMAGE_START_BUTTON));

        rightPanel.add(startButton);

        leftLocationButton.setActionCommand("leftLocationButton");
        rightLocationButton.setActionCommand("rightLocationButton");
        upLocationButton.setActionCommand("upLocationButton");
        downLocationButton.setActionCommand("downLocationButton");
        leftScaleButton.setActionCommand("leftScaleButton");
        rightScaleButton.setActionCommand("rightScaleButton");
        upScaleButton.setActionCommand("upScaleButton");
        downScaleButton.setActionCommand("downScaleButton");
        startButton.setActionCommand("startButton");

        leftLocationButton.setToolTipText("快捷键A");
        rightLocationButton.setToolTipText("快捷键D");
        upLocationButton.setToolTipText("快捷键W");
        downLocationButton.setToolTipText("快捷键S");
        leftScaleButton.setToolTipText("快捷键J");
        rightScaleButton.setToolTipText("快捷键L");
        upScaleButton.setToolTipText("快捷键I");
        downScaleButton.setToolTipText("快捷键K");

        leftLocationButton.addActionListener(this);
        rightLocationButton.addActionListener(this);
        upLocationButton.addActionListener(this);
        downLocationButton.addActionListener(this);
        leftScaleButton.addActionListener(this);
        rightScaleButton.addActionListener(this);
        upScaleButton.addActionListener(this);
        downScaleButton.addActionListener(this);
        startButton.addActionListener(this);

        //我也不知到为什么要这么写，但是直觉告诉我这样解决问题最快
        leftLocationButton.addKeyListener(this);
        rightLocationButton.addKeyListener(this);
        upLocationButton.addKeyListener(this);
        downLocationButton.addKeyListener(this);
        leftScaleButton.addKeyListener(this);
        rightScaleButton.addKeyListener(this);
        upScaleButton.addKeyListener(this);
        downScaleButton.addKeyListener(this);
        startButton.addKeyListener(this);

        startButton.setEnabled(false);



        rightPanel.setBorder(BorderFactory.createTitledBorder("工具栏"));

        mainPanel.add(rightPanel);
//        rightPanel.setBackground(Color.RED);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String actionId = e.getActionCommand();
        if("connectButton".equals(actionId)){
//            if(deviceComboBox.getItemCount() <=1){
//
//            }

            selectedDeviceEntry = deviceComboBox.getItemAt(0);
            if("0".equals(selectedDeviceEntry.getKey())){
                JOptionPane.showMessageDialog(null, "请选择设备！", "提示",JOptionPane.ERROR_MESSAGE);
                return;
            }
            //连接操作
            //1.分辨率
            boolean isConnected =  connectDevice(selectedDeviceEntry.getKey().toString().trim());
            if(isConnected){
                connectStatusText.setText(selectedDeviceEntry.toString()+"已连接");
                centerPanel.setDeviceEntry(selectedDeviceEntry);
            }else{
                JOptionPane.showMessageDialog(null, "连接失败，请重试", "提示",JOptionPane.ERROR_MESSAGE);
                return;
            }
            //2.开启截图进程
            if(refreshThread == null){
                refreshThread = new Thread(){
                    @Override
                    public void run() {
                        while (!this.isInterrupted()){
                            if(!isRun){
                                break;
                            }

                            if(selectedDeviceEntry != null && !"0".equals(selectedDeviceEntry.getKey())){

                                AdbShellUtil.executeShell2("adb shell screencap -p /sdcard/screen.png");
                                AdbShellUtil.executeShell2("adb pull /sdcard/screen.png ./"+USER_SCREENSHOT_FOLDER+"/"+selectedDeviceEntry.getKey()+".png");
                                File screenFile = new File("./"+USER_SCREENSHOT_FOLDER+"/"+selectedDeviceEntry.getKey()+".png");
                                if(screenFile.exists()){
                                    screenshotLabel = new JLabel(new ImageIcon(screenFile.getAbsolutePath()));
                                    centerPanel.setDeviceEntry(selectedDeviceEntry);
                                    repaint();
                                }
                            }
                            deviceComboBox.removeAllItems();
                            deviceMap.clear();

                            //执行adb devices
                            try {
                                deviceMap =  (HashMap<String,String>) AdbShellUtil.getAllDeviceInfo();

                                //遍历deviceMap
                                Iterator iterator = deviceMap.entrySet().iterator();
                                while (iterator.hasNext()){
                                    Map.Entry entry = (Map.Entry<String,String>)iterator.next();
                                    DeviceEntry<String,String> deviceEntry = new DeviceEntry<String, String>(entry.getKey().toString(),entry.getValue().toString());

                                    //过滤异常设备
                                    if(!"".equals(entry.getKey().toString()) && !"".equals(entry.getValue().toString())){
                                        deviceComboBox.addItem(deviceEntry);
                                    }
                                }

                                if(deviceComboBox.getItemCount() == 0){
                                    deviceComboBox.addItem(new DeviceEntry<String, String>("0","-请选择设备-"));
                                    selectedDeviceEntry = null;
                                    connectStatusText.setText("未连接");
                                    showResolutionRatioText.setText("...");
                                    centerPanel.setDeviceEntry(null);
                                    startButton.setEnabled(false);
                                }
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                            try {
                                //15s刷新一次
                                Thread.sleep(15000);

                            } catch (InterruptedException interruptedException) {
//                                interruptedException.printStackTrace();
                                break;
                            }
                        }
                    }
                };
                refreshThread.start();
            }
            //3.开始按钮置为可用状态
            startButton.setEnabled(true);

            return;
        }
        if("refreshButton".equals(actionId)){
            deviceComboBox.removeAllItems();
            deviceMap.clear();

            //执行adb devices
            try {
                deviceMap =  (HashMap<String,String>) AdbShellUtil.getAllDeviceInfo();

                //遍历deviceMap
                Iterator iterator = deviceMap.entrySet().iterator();
                while (iterator.hasNext()){
                    Map.Entry entry = (Map.Entry<String,String>)iterator.next();
                    DeviceEntry<String,String> deviceEntry = new DeviceEntry<String, String>(entry.getKey().toString(),entry.getValue().toString());

                    //过滤异常设备
                    if(!"".equals(entry.getKey().toString()) && !"".equals(entry.getValue().toString())){
                        deviceComboBox.addItem(deviceEntry);
                    }
                }

                if(deviceComboBox.getItemCount() == 0){
                    deviceComboBox.addItem(new DeviceEntry<String, String>("0","-请选择设备-"));
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return;
        }
        //单击事件
        if("leftLocationButton".equals(actionId)){

            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridX(centerPanel.getGrid().getX()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectX(centerPanel.getRect().getX()-1);
            }


        }else if("rightLocationButton".equals(actionId)){
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridX(centerPanel.getGrid().getX()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectX(centerPanel.getRect().getX()+1);
            }
        }else if("upLocationButton".equals(actionId)){
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridY(centerPanel.getGrid().getY()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectY(centerPanel.getRect().getY()-1);
            }
        }else if("downLocationButton".equals(actionId)){
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridY(centerPanel.getGrid().getY()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectY(centerPanel.getRect().getY()+1);
            }
        }else if("leftScaleButton".equals(actionId)){
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridWidth(centerPanel.getGrid().getWidth()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectWidth(centerPanel.getRect().getWidth()-1);
            }
        }else if("rightScaleButton".equals(actionId)){
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridWidth(centerPanel.getGrid().getWidth()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectWidth(centerPanel.getRect().getWidth()+1);
            }
        }else if("upScaleButton".equals(actionId)){
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridHeight(centerPanel.getGrid().getHeight()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectHeight(centerPanel.getRect().getHeight()-1);
            }
        }else if("downScaleButton".equals(actionId)){
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridHeight(centerPanel.getGrid().getHeight()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectHeight(centerPanel.getRect().getHeight()+1);
            }
        }else if("startButton".equals(actionId)){
            saveUserConfig();
            startSolution();

        }


    }

    private void saveUserConfig() {
        int gridX = centerPanel.getGrid().getX();
        int gridY = centerPanel.getGrid().getY();
        int gridWidth = centerPanel.getGrid().getWidth();
        int gridHeight = centerPanel.getGrid().getHeight();


        int rectX = centerPanel.getRect().getX();
        int rectY = centerPanel.getRect().getY();
        int rectWidth = centerPanel.getRect().getWidth();
        int rectHeight = centerPanel.getRect().getHeight();

        int level = yibihuaGraph.getLevel();
        File userConfigFile = new File("./"+USER_CONFIG_FOLDER+"/"+"default"+USER_CONFIG_SUFFIX);
        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.x",gridX+"");
        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.y",gridY+"");
        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.width",gridWidth+"");
        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"grid.height",gridHeight+"");

        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.x",rectX+"");
        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.y",rectY+"");
        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.width",rectWidth+"");
        PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"rect.height",rectHeight+"");
    }

    //开始解题
    private void startSolution(){
        startButton.setEnabled(false);
        int retryCount = 0;
        int retryMaxCount = 5;
        while(true){
            AdbShellUtil.executeShell2("adb shell screencap -p /sdcard/screen_0.png");
            AdbShellUtil.executeShell2("adb pull /sdcard/screen_0.png ./"+USER_SCREENSHOT_FOLDER+"/"+selectedDeviceEntry.getKey()+"_0.png");
            File screenFile = new File("./"+USER_SCREENSHOT_FOLDER+"/"+selectedDeviceEntry.getKey()+"_0.png");
            BufferedImage bufferedImage = ImageUtil.getBufferImage(screenFile.getAbsoluteFile());

            boolean flag = true;
            if(bufferedImage == null){
                flag = false;
            }
            if(flag || retryCount>=retryMaxCount){
                break;
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }

            retryCount++;
            System.out.println("截图失败，正在重试"+retryCount+"/"+retryMaxCount);
        }

        this.yibihuaGraph = new YibihuaGraph(true,levelComboBox.getItemAt(0).getKey());
        //保存用户信息



        //PropertiesUtil.writeValue(userConfigFile.getAbsolutePath(),"config.level",level+"");

        //1.截多张图，程序可能会假死，应使用多线程操作，并实时显示进度
        ArrayList<String> cmdList = new ArrayList<>();
        ArrayList<ArrayList<Integer>> res = combine_backtrack((this.yibihuaGraph.getRow()+2)*(this.yibihuaGraph.getCol()+2),2);

        int total = res.size();
        int current = 0;
        for(ArrayList<Integer> list : res){
            current++;
            int percent = (int)((current/(float)total)*100);
            ShowJProgressBar.getInstance().show();
            ShowJProgressBar.getInstance().setValue(percent);
            int []arr = new int[2];
            for(int i=0;i<2;i++){
                arr[i] = list.get(i);
            }

            //
            Point startPoint = this.centerPanel.getGrid().getMobilePosition(arr[0],this.centerPanel.getImageX(),this.centerPanel.getImageY(),this.centerPanel.getScale());
            Point endPoint = this.centerPanel.getGrid().getMobilePosition(arr[1],this.centerPanel.getImageX(),this.centerPanel.getImageY(),this.centerPanel.getScale());
            int x1 = startPoint.x;
            int y1 = startPoint.y;
            int x2 = endPoint.x;
            int y2 = endPoint.y;
            Point cancelPoint = this.centerPanel.getRect().getCenterPoint(this.centerPanel.getImageX(),this.centerPanel.getImageY(),this.centerPanel.getScale());
            int cancelX = cancelPoint.x;
            int cancelY = cancelPoint.y;
//                System.out.println(arr[0] +"," + arr[1]);
//                System.out.println("x1 = "+x1);
//                System.out.println("y1 = "+y1);
//
//                System.out.println("x2 = "+x2);
//                System.out.println("y2 = "+y2);
//            if(!prevCheckConnected(new Point((x1+x2)/2+1,(y1+y2)/2+1),new Point(((x1+x2))/2-1,((y1+y2))/2-1))){
//
//                continue ;
//            }else{
//                System.out.println("add("+arr[0] +"," + arr[1]+"");
//            }

            //滑动
            String cmd0 = "adb -s "+selectedDeviceEntry.getKey()+" shell input swipe "+x2+" "+y2+" "+x1+" "+y1+" 100";
            String cmd1 = "adb -s "+selectedDeviceEntry.getKey()+" shell input swipe "+x1+" "+y1+" "+x2+" "+y2+" 100";
            //截图
            String cmd2 = "adb -s "+selectedDeviceEntry.getKey()+" shell screencap -p /sdcard/screen.png";
            String screenshotFileStr = "./"+MainFrame.USER_SCREENSHOT_FOLDER+"/"+selectedDeviceEntry.getKey()+"("+arr[0]+"_"+arr[1]+").png";
            String cmd3 = "adb -s "+selectedDeviceEntry.getKey()+" pull /sdcard/screen.png "+screenshotFileStr;
            //点击撤销
            String cmd5 = "adb -s "+selectedDeviceEntry.getKey()+" shell input tap "+cancelX+" "+cancelY;

            AdbShellUtil.executeShell2(cmd1);





            AdbShellUtil.executeShell2(cmd2);
            AdbShellUtil.executeShell2(cmd3);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            boolean isSuccess = false;
//            try {
//                //休眠几秒等待截图
//                Thread.sleep(3000);
//                int maxRetryCount = 5;
//                int currentRetryCount = 0;
//                //adb pull 指令有缺陷，有可能会丢包，导致图片无法解析，所以这里解析失败后多重试几次
//                while(true){
//                    File screenshotPngFile = new File(screenshotFileStr);
//                    BufferedImage bufferedImage = ImageUtil.getBufferImage(screenshotPngFile);
//                    if(bufferedImage != null){
//                        isSuccess = true;
//                        break;
//                    }
//
//                    if(currentRetryCount>maxRetryCount){
//                        isSuccess = false;
//                        break;
//                    }
//                    Thread.sleep(3000);
//                    currentRetryCount++;
//                }
//
//
//            } catch (InterruptedException interruptedException) {
//                interruptedException.printStackTrace();
//            }
//            if(!isSuccess){
//                JOptionPane.showMessageDialog(null, "截图失败！", "提示",JOptionPane.ERROR_MESSAGE);
//                break;
//            }

            File screenshotFile = new File(screenshotFileStr);

            if(screenshotFile.exists()){
                //根据截图判断是否联通
                //在连线中随便取5个点

                Point center = new Point((x1+x2)/2,(y1+y2)/2);
                //起点到中点的等分点p1
                Point p1 = new Point((x1+center.x)/2,(y1+center.y)/2);
                //中点到终点的等分点p2
                Point p2 = new Point((center.x+x2)/2,(center.y+y2)/2);
                //
                Point p3 = new Point((center.x+p1.x)/2,(center.y+p1.y)/2);
                Point p4 = new Point((p2.x+center.x)/2,(p2.y+center.y)/2);
                boolean isConnected = checkConnected(screenshotFile,center,p1,p2,p3,p4);
                //如果中间有障碍，就执行回退操作，并重新从终点到起点滑动一次
                if(!isConnected && this.centerPanel.getGrid().checkExistCenterPoint(new Point(arr[0]%(this.centerPanel.getGrid().getRow()+1),arr[0]/(this.centerPanel.getGrid().getCol() +1) ),new Point(arr[1]%(this.centerPanel.getGrid().getRow()+1),arr[1]/(this.centerPanel.getGrid().getCol() +1) ))){
                    for(int k=0;k<= centerPanel.level;k++){
                        AdbShellUtil.executeShell2(cmd5);
                    }
                    AdbShellUtil.executeShell2(cmd0);
                    AdbShellUtil.executeShell2(cmd2);
                    AdbShellUtil.executeShell2(cmd3);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    isConnected = checkConnected(screenshotFile,center,p1,p2,p3,p4);
                }
                if(isConnected){
                    System.out.println("addEdge("+arr[0]+","+arr[1]+");");
                    this.yibihuaGraph.addEdge(arr[0],arr[1]);
                }else{
//                    System.out.println(p1);
//                    System.out.println(p2);
                }
            }
            for(int k=0;k<= centerPanel.level;k++){
                AdbShellUtil.executeShell2(cmd5);
            }

        }

        ShowJProgressBar.getInstance().close();
//            long start = System.currentTimeMillis();
        this.yibihuaGraph.backtrack(deque,0);
        //            long end = System.currentTimeMillis();
        List<LinkedList<Edge>> backtrackResult =this.yibihuaGraph.backtrackResult;
        int size = backtrackResult.size();
        startButton.setEnabled(true);
        if(size ==0){
            JOptionPane.showMessageDialog(null, "未找到答案，请将辅助框对准后重试！", "提示",JOptionPane.ERROR_MESSAGE);
            return;
        }else{
            while(true){
                String[] options= new String[size];
                for(int i=0;i<size;i++){
                    options[i] = (i+1)+"";
                }
                ImageIcon icon = new ImageIcon(IMAGE_HONGBAO_ICON);
                String inputStr = (String)JOptionPane.showInputDialog(null,"共找到"+backtrackResult.size()+"解法,请选择解法","提示框",JOptionPane.QUESTION_MESSAGE,icon,options,options[0]);
                if(inputStr ==null||"".equals(inputStr)){
                    break;
                }

                int selectIndex = Integer.parseInt(inputStr) -1;
                LinkedList<Edge> list = backtrackResult.get(selectIndex);
                for(Edge edge : list){
                    Point startPoint = this.centerPanel.getGrid().getMobilePosition(edge.x,this.centerPanel.getImageX(),this.centerPanel.getImageY(),this.centerPanel.getScale());
                    Point endPoint = this.centerPanel.getGrid().getMobilePosition(edge.y,this.centerPanel.getImageX(),this.centerPanel.getImageY(),this.centerPanel.getScale());
                    String cmd = "adb -s "+selectedDeviceEntry.getKey()+" shell input swipe "+startPoint.x+" "+startPoint.y+" "+endPoint.x+" "+endPoint.y+" 100";
                    AdbShellUtil.executeShell2(cmd);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                }
                break;
//                    String isContinue = JOptionPane.showInputDialog("没解出来?是否换一种解法(yes/no)");
//                    //取消或no都跳出
//                    if("".equals(isContinue) ||isContinue ==null ){
//                        break;
//                    }
//                    isContinue = isContinue.toLowerCase();
//                    if("no".equals(isContinue) || "n".equals(isContinue)){
//                        break;
//                    }

            }



        }
    }
    public static Deque<Edge> deque = new ArrayDeque<>();
    //预处理，白点排除
    private boolean prevCheckConnected(Point point1,Point point2){
        File screenshotFile = new File("./"+MainFrame.USER_SCREENSHOT_FOLDER+"/"+selectedDeviceEntry.getKey()+"_0.png");

        BufferedImage bufferedImage = null;
        try {
            bufferedImage = ImageIO.read(screenshotFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(bufferedImage !=null){
//            System.out.println("point:");
//            System.out.println(point1);
//            System.out.println(point2);
            Color color1 = new Color(bufferedImage.getRGB(point1.x,point1.y));
            Color color2 = new Color(bufferedImage.getRGB(point2.x,point2.y));
            System.out.println(color1);
            System.out.println(color2);
            //检查到一个白色就continue
            if(ImageUtil.checkColorIsSimilar(color1,new Color(255,255,255),1) || ImageUtil.checkColorIsSimilar(color2,new Color(255,255,255),1)){
                return false;
            }
        }

        return true;
    }

    //检查是否联通
    private boolean checkConnected(File screenshotFile,Point point0, Point point1,Point point2,Point point3,Point point4) {
//        if(!screenshotFile.exists()){
//            System.out.println("截图文件丢失");
//            return false;
//        }

        BufferedImage bufferedImage = null;
        try {
            bufferedImage = ImageIO.read(screenshotFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(bufferedImage !=null){
            Color color0 = new Color(bufferedImage.getRGB(point0.x,point0.y));
            Color color1 = new Color(bufferedImage.getRGB(point1.x,point1.y));
            Color color2 = new Color(bufferedImage.getRGB(point2.x,point2.y));
            Color color3 = new Color(bufferedImage.getRGB(point3.x,point3.y));
            Color color4 = new Color(bufferedImage.getRGB(point4.x,point4.y));
            boolean flag0 = ImageUtil.checkColorIsSimilar(color0,ImageUtil.redColor,10);
            boolean flag1 = ImageUtil.checkColorIsSimilar(color1,ImageUtil.redColor,10);
            boolean flag2 = ImageUtil.checkColorIsSimilar(color2,ImageUtil.redColor,10);
            boolean flag3 = ImageUtil.checkColorIsSimilar(color3,ImageUtil.redColor,10);
            boolean flag4 = ImageUtil.checkColorIsSimilar(color4,ImageUtil.redColor,10);
            //System.out.println("("+color1.getRed()+","+color1.getGreen()+","+color1.getBlue()+")");
//            if(ImageUtil.checkColorIsSimilar(color0,ImageUtil.redColor,10) && ImageUtil.checkColorIsSimilar(color1,ImageUtil.redColor,10) && ImageUtil.checkColorIsSimilar(color2,ImageUtil.redColor,10) &&ImageUtil.checkColorIsSimilar(color3,ImageUtil.redColor,10) &&ImageUtil.checkColorIsSimilar(color4,ImageUtil.redColor,10)){
//                return true;
//            }
            return (flag0 && flag1 && flag2 && flag3 && flag4);
        }

        return false;
    }


    //连接设备，并开启截图进程
    private boolean connectDevice(String deviceId) {
        //1.获取分辨率，并更新至状态栏
        String getResolutionRatioCommand = "adb -s "+deviceId +" shell wm size";
        String resolutionRatio =AdbShellUtil.executeShell2(getResolutionRatioCommand);

        Pattern pattern =Pattern.compile("(\\d+x\\d+)");
        Matcher matcher=pattern.matcher(resolutionRatio);
        if(matcher.find()){
            String str = matcher.group(1);

            showResolutionRatioText.setText(str);

            String []resolutionArr = str.split("x");
            int screenWidth = Integer.parseInt(resolutionArr[0]);
            int screenHeight = Integer.parseInt(resolutionArr[1]);
            PropertiesUtil.writeValue("./"+USER_CONFIG_FOLDER+"/"+"default"+USER_CONFIG_SUFFIX,"screen.width",screenWidth+"");
            PropertiesUtil.writeValue("./"+USER_CONFIG_FOLDER+"/"+"default"+USER_CONFIG_SUFFIX,"screen.height",screenHeight+"");
            return true;
        }
        return false;
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        if(e.getSource() == deviceComboBox){
            if (e.getStateChange() == ItemEvent.SELECTED) {
                DeviceEntry<String,String> deviceEntry = (DeviceEntry<String, String>) e.getItem();

                if("".equals(deviceEntry.getValue().toString().trim()) || "".equals(deviceEntry.getKey().toString().trim())){
                    JOptionPane.showMessageDialog(null, "无效的设备id！", "提示",JOptionPane.ERROR_MESSAGE);
                    return;
                }


            }
            return;
        }
        if(e.getSource() == levelComboBox){
            if (e.getStateChange() == ItemEvent.SELECTED) {
                LevelEntry<Integer, String> levelEntry = (LevelEntry<Integer, String>) e.getItem();
                int selectLevel = levelEntry.getKey();
                PropertiesUtil.writeValue("./"+USER_CONFIG_FOLDER+"/"+"default"+USER_CONFIG_SUFFIX,"config.level",selectLevel+"");
                //重新赋值，能少很多bug
                yibihuaGraph = new YibihuaGraph(true, selectLevel);
                if (centerPanel != null) {
                    centerPanel.setLevel(selectLevel);
                }
            }
            return;
        }


    }


    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {

        System.out.println();
        int code = e.getKeyCode();
        if(KeyEvent.VK_A == code){
            System.out.println("a");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridX(centerPanel.getGrid().getX()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectX(centerPanel.getRect().getX()-1);
            }
        }
        if(KeyEvent.VK_W == code){
            System.out.println("w");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridY(centerPanel.getGrid().getY()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectY(centerPanel.getRect().getY()-1);
            }
        }
        if(KeyEvent.VK_S == code){
            System.out.println("s");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridY(centerPanel.getGrid().getY()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectY(centerPanel.getRect().getY()+1);
            }
        }
        if(KeyEvent.VK_D == code){
            System.out.println("d");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridX(centerPanel.getGrid().getX()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectX(centerPanel.getRect().getX()+1);
            }
        }

        if(KeyEvent.VK_J == code){
            System.out.println("j");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridWidth(centerPanel.getGrid().getWidth()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectWidth(centerPanel.getRect().getWidth()-1);
            }
        }
        if(KeyEvent.VK_I == code){
            System.out.println("i");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridHeight(centerPanel.getGrid().getHeight()-1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectHeight(centerPanel.getRect().getHeight()-1);
            }
        }
        if(KeyEvent.VK_K == code){
            System.out.println("k");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridHeight(centerPanel.getGrid().getHeight()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectHeight(centerPanel.getRect().getHeight()+1);
            }
        }
        if(KeyEvent.VK_L == code){
            System.out.println("l");
            if(centerPanel.isSelectedGrid()){
                centerPanel.setGridWidth(centerPanel.getGrid().getWidth()+1);
            }
            if(centerPanel.isSelectedRect()){
                centerPanel.setRectWidth(centerPanel.getRect().getWidth()+1);
            }
        }


    }

    @Override
    public void keyReleased(KeyEvent e) {

    }


    public static int a[] = new int[25];
    //用回溯法求组合
    public static ArrayList<ArrayList<Integer>> combine_backtrack(int n, int r)
    {
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();

        int i = 0;
        int j = 0;
        a[i]=0;
        do{
            if(a[i]<=n-r+i){
                if(i==r-1){
                    ArrayList tempList = new ArrayList();
                    for(j=0;j<r;j++){
                        tempList.add(a[j]);
                    }
                    result.add(tempList);
                    a[i]++;
                    continue;
                }else{
                    i++;
                    a[i]=a[i-1]+1;
                }
            }else{
                if(i==0){
                    return result;
                }else{
                    i--;
                    a[i]++;
                }
            }
        }while(true);
    }

}
